const { learning_route, tech, depend } = require("../models");
const db = require("../models");
const Tech = db.tech;
const Depend = db.depend;
const Learning_route = db.learning_route;

exports.findAll = (req, res) => {
  Learning_route.findAll({ where: { user_mail: req.query.user_mail } })
    .then((data) => {
      res.setHeader("Access-Control-Allow-Origin", '*')
      res.send(data);
    })
    .catch((err) => {
      res.status(500).send({
        message: err.message || "未查询到该用户的学习路线",
      });
    });
}

exports.findNodes= async(req, res) => {
  let global_x=[];
  let max_y = 0;
  let tmp_tech_ids = [];
  let ret_val = [{}];
  
  await Learning_route.findAll({ where: { user_mail: req.query.user_mail },raw: true }).then((data)=>{tmp_tech_ids = data})

  for(let i=0;i<tmp_tech_ids.length;i++){
    await Tech.findOne({where: { tech_id:tmp_tech_ids[i].tech_id },raw: true}).then((data)=>{
      console.log(data)
      if(data.tech_level>max_y){
        max_y = data.tech_level;
      }
      ret_val[i]={};
      ret_val[i].data={};
      ret_val[i].position={};
      ret_val[i].id = data.tech_id.toString();
      ret_val[i].data.label = data.tech_name
    })
  }
  
  for(let i=0;i<=max_y;i++){
    global_x[i]=0;
  }

  for(let i=0;i<tmp_tech_ids.length;i++){
    await Tech.findOne({where: { tech_id:tmp_tech_ids[i].tech_id },raw: true}).then((data)=>{
      ret_val[i].position.y = max_y - data.tech_level;
      ret_val[i].position.y = ret_val[i].position.y * 100;
      ret_val[i].position.x = global_x[data.tech_level];
      global_x[data.tech_level] += 200;
    })
  }

  res.setHeader("Access-Control-Allow-Origin", '*')
  res.send(ret_val);
}

exports.findEdges = async(req, res) => {
  let global_id=0;
  let tmp_tech_ids = [];
  let ret_val = [{}];

  await Learning_route.findAll({ where: { user_mail: req.query.user_mail },raw: true }).then((data)=>{tmp_tech_ids = data})

  for(let i=0;i<tmp_tech_ids.length;i++){
    await Depend.findAll({where: { tech_id:tmp_tech_ids[i].tech_id },raw: true}).then((data)=>{
      for(let j=0;j<data.length;j++){
        ret_val[global_id]={};
        ret_val[global_id].id = global_id.toString();
        ret_val[global_id].target = data[j].dep_id.toString();
        ret_val[global_id].source = data[j].tech_id.toString();
        global_id += 1;
      }
    })
  }

  res.setHeader("Access-Control-Allow-Origin", '*')
  res.send(ret_val);
}

exports.findBasic = (req, res) => {
  Learning_route.findAll({ where: { user_mail: req.query.user_mail,process: 1 } })
    .then((data) => {
      res.setHeader("Access-Control-Allow-Origin", '*')
      res.send(data);
    })
    .catch((err) => {
      res.status(500).send({
        message: err.message || "未查询到该用户的学习路线",
      });
    });
}

exports.findBasicName = async(req, res) => {
  let data = await Learning_route.findAll({ where: { user_mail: req.query.user_mail,process: 1 }, raw: true })
  let ret_val = [];
    for(let i=0;i<data.length;i++){
      await Tech.findOne({where:{tech_id:data[i].tech_id}, raw: true}).then((data)=>{ret_val[i]=data.tech_name})
    }

    res.setHeader("Access-Control-Allow-Origin", '*')
    res.send(ret_val);
}

exports.findTarget = (req, res) => {
  Learning_route.findAll({ where: { user_mail: req.query.user_mail,origin: true } })
    .then((data) => {
      res.setHeader("Access-Control-Allow-Origin", '*')
      res.send(data);
    })
    .catch((err) => {
      res.status(500).send({
        message: err.message || "未查询到该用户的学习路线",
      });
    });
}

exports.findTargetName = async(req, res) => {
  let data = await Learning_route.findAll({ where: { user_mail: req.query.user_mail,origin: true }, raw: true })
  let ret_val = [];
    for(let i=0;i<data.length;i++){
      await Tech.findOne({where:{tech_id:data[i].tech_id}, raw: true}).then((data)=>{ret_val[i]=data.tech_name})
    }

    res.setHeader("Access-Control-Allow-Origin", '*')
    res.send(ret_val);
}

exports.delOne = (req, res) => {
  Learning_route.destroy({ where: { user_mail: req.query.user_mail, tech_id: req.query.tech_id } })
    .then((data) => {
      res.setHeader("Access-Control-Allow-Origin", '*')
      res.send(data);
    })
    .catch((err) => {
      res.status(500).send({
        message: err.message || "学习路线中不存在该技术",
      });
    });
}

exports.addOne = async(req, res) => {
  let m_ready = await checkReady(req.query.user_mail, req.query.tech_id)
  
  Learning_route.create({ user_mail: req.query.user_mail, tech_id: req.query.tech_id, process: 0, ready: m_ready, origin: 1 })
    .then((data) => {
      console.log("add success")
      res.setHeader("Access-Control-Allow-Origin", '*')
      res.send("ok");
    })
    .catch((err) => {
      res.status(500).send({
        message: err.message || "添加技术失败",
      });
    });
}

exports.addProcess = async(req, res) => {
  let m_exist = false;
  await checkExist(req.query.user_mail,req.query.tech_id).then((ret_val)=>{console.log(ret_val);m_exist = ret_val})
  console.log(m_exist)
  if(m_exist){
    Learning_route.update({process: 1},{where: { user_mail: req.query.user_mail, tech_id: req.query.tech_id}} ).then((data) => {
      res.setHeader("Access-Control-Allow-Origin", '*')
      res.send(data);
    })
  }else{
    let m_ready =await checkReady(req.query.user_mail, req.query.tech_id);
    Learning_route.create({ user_mail: req.query.user_mail, tech_id: req.query.tech_id, process: 1, ready: m_ready })
    .then((data) => {
      res.setHeader("Access-Control-Allow-Origin", '*')
      res.send(data);
    })
    .catch((err) => {
      res.status(500).send({
        message: err.message || "添加技术失败",
      });
    });
  }
}

exports.checkReadyForUser = async(user_mail) =>{
  let candidate = await Learning_route.findAll({where:{
    user_mail: user_mail
  },raw: true})

  for(let i=0;i<candidate.length;i++){
    let m_ready = await checkReady(user_mail,candidate[i].tech_id)
    if(m_ready){
      await Learning_route.update({ready: true},{
        where: {tech_id: candidate[i].tech_id}
      })
    }
  }
}

async function checkReady(user_mail, tech_id) {
  let tech_dep = [];
  await Depend.findAll({ where: { tech_id: tech_id },raw: true }).then((data) => { 
    tech_dep = data;
  }).catch((err) => {throw err});

  for (let val = 0; val < tech_dep.length; val++) {
    let ok = true;
    console.log(1)
    await Learning_route.findOne({ where: { user_mail: user_mail, tech_id: tech_dep[val].dep_id },raw: true }).then((data) => {
      if (data === null || data.process !== 1) {
        ok = false;
      } else {
        ok = true;
      }
    }).catch((err) => {throw err})


    if (ok == false) {
      return false;
    }
  }

  return true;
}

//check whether the study target exists
const checkExist = async(user_mail, tech_id) => {
  let ret_val = false;

  await Learning_route.findOne({ where: { tech_id: tech_id, user_mail: user_mail },raw: true }).then((data) => {

    if (data === null) {
      ret_val =  false;
    }
    else{
      ret_val =  true;
    }
  })
  return ret_val;
}

async function recursiveAdd(user_mail, tech_id) {
  let one_deps = [];
  await depend.findAll({ where: { tech_id: tech_id },raw: true }).then((data) => { one_deps = data });
  
  for (let j = 0; j < one_deps.length; j++) {
    let m_exist = false;
    await checkExist(user_mail, one_deps[j].dep_id).then((ret_val) => {m_exist = ret_val})

    if (!m_exist) {
      let m_ready =await checkReady(user_mail, one_deps[j].dep_id);

      Learning_route.create({ user_mail: user_mail, tech_id: one_deps[j].dep_id, process: 0, ready:m_ready  });
      recursiveAdd(user_mail, one_deps[j].dep_id);
    }
  }
}

// generate route after selecting target
exports.generateRoute = async(req, res) => {
  let tech_dep = [];
  learning_route.findAll({ where: { user_mail: req.query.user_mail },raw: true })
    .then((data) => {
      console.log(data);
      tech_dep = data
      for (var i = 0; i < tech_dep.length; i++) {
        recursiveAdd(req.query.user_mail, tech_dep[i].tech_id).catch((err) => {
          res.status(500).send({
            message: err.message || "添加技术失败",
          });
        });;
      }

      res.setHeader("Access-Control-Allow-Origin", '*')
      res.send("ok");
    })
    .catch((err) => {
      res.status(500).send({
        message: err.message || "添加技术失败",
      });
    });
}